(ns jumpluff.datasets
  (:require [cljs.core.async :as async]
            [clojure.string :as s]
            [jumpluff.utils :refer [log]])
  (:require-macros [cljs.core.async.macros :as async-macros]
                   [jumpluff.datasets :refer [update-vec-from-index-map]]))

(def fs (js/require "fs"))
(def csv (js/require "csv"))

(defn- parse-csv-vec
  "Validate and translate `vec` by each provided index"
  [columns vec]
  (update-vec-from-index-map
   vec columns <>
   :index-nicknames (if (and (not-empty <>)
                             (string? <>))
                      (->> (s/split <> ",")
                         (map s/trim)
                         (remove empty?)
                         (map s/lower-case)))
   :index-gps (->> <>
                 (re-find #"(-?\d{1,2}\.\d*,-?\d{1,2}\.\d*)")
                 second)
   :index-description (s/replace (or <> "") #"／" "\n")
   :index-ex (when-let [ex-str (and (string? <>)
                                    (not-empty <>)
                                    (s/upper-case <>))]
               (if (s/includes? ex-str "EX-T")
                 :ex-triggered
                 :ex-possible))))

(defn- load-csv-file [filename]
  (let [fs-chan (async/chan)
        csv-chan (async/chan)]
    (async-macros/go
      (.readFile fs filename #(async/put! fs-chan (or %2 "")))
      (.parse csv (async/<! fs-chan)
              #(async/put! csv-chan (js->clj (or %2 []))))
      (async/close! fs-chan))
    csv-chan))

(defn load-dataset
  "Load a dataset into `csv-files`"
  [csv-files base-dir [name {:keys [columns source]}]]
  (async-macros/go
    (swap! csv-files assoc source
           (map #(parse-csv-vec columns %)
                (rest (async/<! (->> source
                                   (str base-dir "/")
                                   load-csv-file)))))
    (log "Loaded dataset " name ":" source " containing "
         (count (get @csv-files source))
         " points")))
